/**
 * @Title: 充电报文类
 * @Package com.dz.ss.controller
 * @author pengyu
 * @date 2015年12月15日 上午10:21:55
 * @version V1.0
 */
package tt.dz.mvc.controller.middleware;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import tt.dz.dao.ext.charger.OmsChargerDao;
import tt.dz.dao.ext.charger.OmsChargerRateDao;
import tt.dz.dao.ext.system.OmsOperationSpListDao;
import tt.dz.entity.base.JsonCommon;
import tt.dz.entity.charger.OmsCharger;
import tt.dz.entity.charger.OmsChargerRate;
import tt.dz.entity.system.OmsOperationSpList;
import tt.dz.mvc.controller.base.BaseController;
import tt.dz.service.imp.middleware.Ev3c2EncapsulationServiceImpl;
import tt.dz.service.middleware.MessageService;
import tt.dz.service.middleware.OmsChargeService;
import tt.dz.service.sys.ChargerService;
import tt.dz.tcp.socket.MessageFuture;
import tt.dz.util.OmsConstant;
import tt.dz.util.RedisClient;
import tt.dz.util.StringUtil;

@Controller
@RequestMapping("/chargeControll")
public class ChargeController extends BaseController{
	private Log log = LogFactory.getLog(ChargeController.class);
	/**
	 * 日志对象
	 */
	private Logger logger = LoggerFactory.getLogger(ChargeController.class);
	@Resource
	OmsChargeService omsChargeService;
	@Resource
	OmsChargerDao omsChargerDao;
	@Resource(name = "ev3c2MessageServiceImpl")
	MessageService ev3c2MessageService;
	@Resource
	ChargerService chargerService;
	@Resource
	OmsChargerRateDao omsChargerRateDao;
	@Resource
	OmsOperationSpListDao omsOperationSpListDao;
	// 3.1.18. 
	//AS 请求 OMS ，OMS 下发充电 socket，只下发，短连接
//	@RequestMapping("/startCharge") 
	@RequestMapping(value="/startCharge")
	@ResponseBody
	public JsonCommon<String> startCharge(HttpServletRequest request, HttpServletResponse response) throws Exception {
		log.info("start charging");
		//最新的版本中下发时按照协议类型和协议版本号来,放在Stringutil.getParameterByOms中去处理
		String chargerId = request.getParameter("chargerId");
		String portNo = request.getParameter("portNo");
		String controlType = request.getParameter("controlType");
		if(StringUtil.isBlank(chargerId) || StringUtil.isBlank(portNo) || StringUtil.isBlank(controlType))
			return new JsonCommon<>(OmsConstant.MsgFaultCodeEnum.MissParameter.value(), OmsConstant.MsgFaultCodeEnum.MissParameter.desc());

		OmsCharger query = new OmsCharger();
		query.setCharger_id(chargerId);
		OmsCharger omsCharger = omsChargerDao.findOneExample(query, null, null);
		if(omsCharger==null){
			return new JsonCommon<>(OmsConstant.MsgFaultCodeEnum.MissParameter.value(), OmsConstant.MsgFaultCodeEnum.MissParameter.desc());
		}
		//ev3c报文头
//		String chargerId = request.getParameter("chargerId");
		//ev3c报文体
		String openRestrictedData = request.getParameter("limit_data");//开启限制数据：不同充电模式下对应的计算量作为停机条件。自动充满停机方式下无意义。低字节在前，高字节在后。电量控制,单位为“度”，精确到0.01,传输数据放大100倍；时间控制，单位为“秒“，精确到1,；金额控制，单位为“元”，精确到0.01，传输数据放大100倍。
		// 1.将页面数据乘以100  2.计算的到BIN码  3.反转字符串
		openRestrictedData = StringUtil.reverseStr(StringUtil.complement(Integer.toHexString((int) (Float.parseFloat(openRestrictedData) * 100)).toString(), 8), 2);
		String timeStart = request.getParameter("time_start"); // 定时启动时间，分，时，日，月，对于即时充电，该时间无意义。例如：定时1月14日12时50分开始启动充电，则发送0x01,0x14, 0x12,0x50
		//定时启动时间，分，时，日，月，对于即时充电，该时间无意义   例如：定时1月14日12时50分开始启动充电，则发送0x01,0x14, 0x12,0x50
		String startTime = request.getParameter("startTime");
		String userCard = request.getParameter("userCard");
		//充电数据上传间隔	BIN码	1		每两次充电数据上传间的间隔时间，单位：秒
		String charging_data_upload_interval = request.getParameter("charging_data_upload_interval");
		//电池详情上传间隔  每两次电池详情上传间的间隔时间，单位：秒
		String battery_details_upload_interval = request.getParameter("battery_details_upload_interval");
		Map<String,String> map  = new HashMap<String,String>();
		map.put("chargerId", chargerId);
		map.put("portNo",portNo);
		map.put("controlType",controlType);
		map.put("openRestrictedData",openRestrictedData);
		map.put("timeStart",timeStart);
		map.put("startTime",startTime);
		map.put("userCard",userCard);
		map.put("charging_data_upload_interval",charging_data_upload_interval);
		map.put("battery_details_upload_interval",battery_details_upload_interval);
		map.put("protocol_type",omsCharger.getProtocol_type());
		map.put("protocol_version",omsCharger.getProtocol_version());
//		return omsChargeService.startCharge(chargerId, userCard);
		MessageFuture future = omsChargeService.startCharge(map);
		JsonCommon<String> json = new JsonCommon();
		if(future != null)
		{
			if(future.await(60000))
			{
				if(future.isSuccess())
				{
					json.setCode("200");
					json.setMsg("chargerId " + chargerId + " startCharge sendSocket success");
//					json.setPojo(charge_jrnl);
				}
				else
				{
					json.setCode(future.getErrorCode());
					json.setMsg(future.getErrorMessage());
				}
			}
			else
			{
				json.setCode("400");
				json.setMsg("Timeout for waiting response from charger");
			}
			log.info(future.isDone());
			log.info(future.isSuccess());
			log.info(future.getErrorCode());
			log.info(future.getErrorMessage());


		}
		return json;
	}	
	
	//AS 请求 OMS ，OMS 下发充电 socket，只下发，短连接  startChargeReturn  //php中叫stopCharge
	@RequestMapping(value="/stopCharge")
	@ResponseBody
	public JsonCommon<String> stopCharge(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Map<String,String> map = StringUtil.getParameterByOms(request);
		return omsChargeService.stopCharge(map);
//		String responseMsgHeader,responseMsgBody,code,msg; 
//		String chargerId = request.getParameter("chargerId");//AS传值
//		String userCard = request.getParameter("userCard");//AS传值		
//		String portNo = request.getParameter("portNo");//AS传值		
////		String code_type = "12";
//		String control_type = "04";
//		responseMsgBody = portNo+control_type+userCard;
//		responseMsgHeader ="68"+StringUtil.complement(String.valueOf(responseMsgBody.length()), 4)+"01"+"000000"+"0001"+chargerId+"12"+StringUtil.now14time();
//		StringUtil.sendSocket(responseMsgHeader+responseMsgBody);
//		JsonCommon<String> json = new JsonCommon<String>();
//		json.setCode("200");
//		json.setMsg("stopCharge success");
//		json.setPojo(responseMsgHeader+responseMsgBody);
//		return json;
	}		
	//重启
	@RequestMapping(value="/restartCharger")
	@ResponseBody
	public JsonCommon<String> restartCharger(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Map<String,String> map = StringUtil.getParameterByOms(request);
		return omsChargeService.restartCharger(map);
	}	
	
//	public static void main(String args[]){
//		Map<String,String> map  = new HashMap<String,String>();
//		map.put("chargerId", null);
//		System.out.println(map.get("chargerId"));
//	}
	//固件更新
	@RequestMapping(value="updateFirmware",method=RequestMethod.POST)
	@ResponseBody
	public JsonCommon<String> updateFirmware(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Map<String,String> map = StringUtil.getParameterByOms(request);
		return omsChargeService.updateFirmware(map);
	}	
	
	//2.0报文   6.8设置/查询电桩参数
	@RequestMapping(value="/queryOrSetParam", method = RequestMethod.POST)
	@ResponseBody
	public JsonCommon<String> queryOrSetParam(HttpServletRequest request, HttpServletResponse response) throws Exception {
//		Map<String,String> map = StringUtil.getParameterByOms(request);
		SimpleDateFormat format = new SimpleDateFormat("HHmmss");
		StringBuilder sb = new StringBuilder("");
		String ev3c_frameCode="21";
		String ev3c_msgBody ="";
		String encryption ="00";
//		String portNo ="00";//queryOrSetParamType 为07 的时候，这个参数应该是 01 02 等等
		String portNo ="0";//queryOrSetParamType 为07 的时候，这个参数应该是 01 02 等等
		String chargerType ="1";//高4位：0：交流桩   1：直流桩  3：其它
		Map<String,String> map = new HashMap<String,String>();
		//报文2.0  6.8设置/查询电桩参数
		String chargerId = request.getParameter("chargerId");
		OmsCharger query = new OmsCharger();
		query.setCharger_id(chargerId);
		OmsCharger charger = omsChargerDao.findOneExample(query, null, null);
		if(charger.getCharger_type()!=null){
			chargerType = String.valueOf(charger.getCharger_type());
		}
		String queryOrSet = request.getParameter("queryOrSet");
		String queryOrSetParamType = request.getParameter("queryOrSetParamType");
		map.put("queryOrSet", queryOrSet);//操作类型  0x00: 查询，0x01：设置
		map.put("queryOrSetParamType", queryOrSetParamType);//参数类型	BCD码 1查询/设置参数的类型，详见“参数列表”  00 01 02等
		log.info("chargerId = "+chargerId+" queryOrSet = "+queryOrSet +" queryOrSetParamType = "+ queryOrSetParamType);
		sb.append(queryOrSet+queryOrSetParamType);
		switch(queryOrSet){
		case "00":
			break;
		case "01":
			switch(queryOrSetParamType){
			case "00"://对时
				String time =  request.getParameter("time");//
				sb.append(time);
				ev3c_msgBody = sb.toString();//YYYY-MM-DD-hh-mm-ss 例如：0x20 0x15 0x05 0x10 0x13 0x20 0x11,表示2015年5月10日13时20分11秒
				break;
			case "01"://运营二维码
				String new_qr_code = chargerService.updateQrCode(chargerId);
				sb.append(new_qr_code);
				ev3c_msgBody  = sb.toString();
				break;
			case "02"://电费费率
				String rate_schema_charge_fee =  request.getParameter("rate_schema_charge_fee");//
//				RedisClient.getJedisInstance().set(chargerId+"_rate_schema_charge_fee", rate_schema_charge_fee);
				RedisClient.putString(chargerId+"_rate_schema_charge_fee", rate_schema_charge_fee);
				OmsChargerRate omsChargerRate_query = new OmsChargerRate();
				omsChargerRate_query.setRate_schema(Integer.valueOf(rate_schema_charge_fee));
				List<OmsChargerRate> omsChargerRate_list = omsChargerRateDao.findExample(omsChargerRate_query, null, null," serial_no ",1);//正序
				int size = omsChargerRate_list.size();	//当日分配的总时间段数（至少一个时间段：00：00:00～23：59:59）	BIN	1
				if(size<=0){
					return  new JsonCommon<>(OmsConstant.ErrorCodeEnum.MessageParamValueError.value(), OmsConstant.ErrorCodeEnum.MessageParamValueError.desc()) ;
				}
				String size_bin = Integer.toHexString(size);
				sb.append(size_bin);
//				for(OmsChargerRate rate : omsChargerRate_list){
//					String end_time_temp  =format.format(rate.getEnd_time());
//					float rate_temp = rate.getRate().floatValue();
//					String rate_bin = StringUtil.float10to16ByParamDesc(String.valueOf(rate_temp), 100, 4);
//					sb.append("FFFFFFFF"+ end_time_temp + rate_bin);
//				}
				sb.append("00000000000000");//开始时间
				for(OmsChargerRate rate : omsChargerRate_list){
					String end_time_temp  =format.format(rate.getEnd_time());
					float rate_temp = rate.getRate().floatValue();
					String rate_bin = StringUtil.float10to16ByParamDesc(String.valueOf(rate_temp), 100, 4);
					sb.append(rate_bin + end_time_temp);
				}
				ev3c_msgBody = sb.toString();
				break;
			case "03"://服务费
				String rate_schema_charge_service =  request.getParameter("rate_schema_charge_fee");//
//				RedisClient.getJedisInstance().set(chargerId+"_rate_schema_service_fee", rate_schema_charge_service);
				RedisClient.putString(chargerId+"_rate_schema_service_fee", rate_schema_charge_service);
				OmsChargerRate omsChargerRate_service_query = new OmsChargerRate();
				omsChargerRate_service_query.setRate_schema(Integer.valueOf(rate_schema_charge_service));
				List<OmsChargerRate> omsChargerRate_service_list = omsChargerRateDao.findExample(omsChargerRate_service_query, null, null," serial_no ",1);//正序
				int service_size = omsChargerRate_service_list.size();	//当日分配的总时间段数（至少一个时间段：00：00:00～23：59:59）	BIN	1
				if(service_size<=0){
					return  new JsonCommon<>(OmsConstant.ErrorCodeEnum.MessageParamValueError.value(), OmsConstant.ErrorCodeEnum.MessageParamValueError.desc()) ;
				}
				int charge_mode = omsChargerRate_service_list.get(0).getCharge_mode();
				sb.append(Integer.toHexString(charge_mode));
				switch(charge_mode){//收费模式：0：按时间收费，1：按次数收费 
				case 0:
					sb.append("FFFF");//按次数收费填充此参数，若按时间设置费率，用0xFF 0xFF填充
					String service_size_bin = Integer.toHexString(service_size);
					sb.append(service_size_bin);
					for(OmsChargerRate rate : omsChargerRate_service_list){
						String end_time_temp  =format.format(rate.getEnd_time());
						float rate_temp = rate.getRate().floatValue();
						String rate_bin = StringUtil.float10to16ByParamDesc(String.valueOf(rate_temp), 100, 4);
						sb.append("FFFFFFFF"+ end_time_temp + rate_bin);
					}
					ev3c_msgBody = sb.toString();
					break;
				case 1:
					float rate_temp = omsChargerRate_service_list.get(0).getRate().floatValue();
					String rate_bin = StringUtil.float10to16ByParamDesc(String.valueOf(rate_temp), 100, 4);
					sb.append(rate_bin);
					ev3c_msgBody = sb.toString();
					break;
				default:
					return  new JsonCommon<>(OmsConstant.ErrorCodeEnum.MessageParamValueError.value(), OmsConstant.ErrorCodeEnum.MessageParamValueError.desc()) ;
				}
				break;
			case "05":
				log.info("white_list begin");  
//				map.put("operation_type", operation_type);
//				map.put("whitelist_number", whitelist_number);
				String operation_type =  request.getParameter("operation_type");//操作方法：  0x01  增加   0x02  删除  0x0F  其它
				sb.append(operation_type);
				String white_list =  request.getParameter("white_list");//
				String[] array = white_list.split(",");
				if(array.length<16){
					sb.append("0"+Integer.toHexString(array.length));
				}else{
					sb.append(Integer.toHexString(array.length));
				}
				for(String temp :array){
					sb.append(temp);
				}
//				List<String> list_5 = StringUtil.request2List(request, "white_list");
//				if(list_5.size()>0){
//					sb.append(Integer.toHexString(list_5.size()));
//					for(String temp:list_5){
//						sb.append(temp);
//					}
//				}
				ev3c_msgBody = sb.toString();
				log.info("white_list ev3c_msgBody= "+ev3c_msgBody	);
				break;
			case "06"://设置无   当前用户卡号
				return  new JsonCommon<>(OmsConstant.ErrorCodeEnum.MessageParamValueError.value(), OmsConstant.ErrorCodeEnum.MessageParamValueError.desc()) ;
			case "07"://设置无  电桩当前状态
				return  new JsonCommon<>(OmsConstant.ErrorCodeEnum.MessageParamValueError.value(), OmsConstant.ErrorCodeEnum.MessageParamValueError.desc()) ;
			case "08":
				String serial_no = request.getParameter("serial_no");
				if(!StringUtil.isNumeric(serial_no)){
					return  new JsonCommon<>(OmsConstant.ErrorCodeEnum.MessageParamValueError.value(), OmsConstant.ErrorCodeEnum.MessageParamValueError.desc()) ;
				}
				sb.append(Integer.toHexString(Integer.valueOf(serial_no)));
				ev3c_msgBody = sb.toString();
				break;
			default:
				return  new JsonCommon<>(OmsConstant.ErrorCodeEnum.MissParam.value(), OmsConstant.ErrorCodeEnum.MissParam.desc()) ;
			}
			break;	
		default:
			return  new JsonCommon<>(OmsConstant.ErrorCodeEnum.MissParam.value(), OmsConstant.ErrorCodeEnum.MissParam.desc()) ;
		}
		Ev3c2EncapsulationServiceImpl ev3c2EncapsulationServiceImpl = new Ev3c2EncapsulationServiceImpl();
//		log.info("ev3c_msgBody = "+ ev3c_msgBody +" ev3c_frameCode = "+ev3c_frameCode+" chargerId = "+ chargerId + " chargerType = "+chargerType +" portNo = "+portNo +" encryption = "+encryption );
		String communicationNo = "0001";//默认为豪特的通讯编号
		log.info(" omsOperationSpListDao = "+omsOperationSpListDao);
		if(StringUtil.isNotBlank(charger.getOper_merchant_id()) && omsOperationSpListDao!= null){
			String condition = " where oper_merchant_id  = '"+ charger.getOper_merchant_id()+"'";
			OmsOperationSpList omsOperMerchant = omsOperationSpListDao.findOneExampleByCondition(new OmsOperationSpList(), condition);
			log.info(omsOperMerchant.toString());
			if (omsOperMerchant != null && StringUtil.isNotBlank(omsOperMerchant.getCommunication_no()))
			{
				communicationNo = omsOperMerchant.getCommunication_no();
			}			
		}
		String msg = ev3c2EncapsulationServiceImpl.generateEv3c2SendMsg(ev3c_msgBody, ev3c_frameCode, chargerId, chargerType, portNo, encryption,communicationNo);
//		String ev3c_msgHeader = "68"+StringUtil.ev3cMsgBodyBin(ev3c_msgBody)+ev3c_frameCode+"0001"+chargerId+"000000"+"0001"+chargerId+ev3c_frameCode+StringUtil.now14time();
		log.info("queryOrSetParam_sendMsg = "+msg);
		ev3c2MessageService.sendNoWait(msg, chargerId);
		return OmsConstant.jsonSuccess;
	}
	
	public  static void main(String[] args){
		String openRestrictedData ="000000";
		openRestrictedData = StringUtil.reverseStr(StringUtil.complement(Integer.toHexString((int) (Float.parseFloat(openRestrictedData) * 100)).toString(), 8), 2);
		System.out.println(openRestrictedData);
	}
}
